//
//  XMPages.swift
//  sinaDemo
//
//  Created by Xueming on 2021/4/15.
//  update by Xueming on 2024/9/2.

import Foundation
import UIKit
let xmpageVersion = 0.1.0
//import JKSwiftExtension
//也可以不复用。复用cell的话需要频繁移除和添加childView
private let cellId = "pageCollectionCell"
enum selectedLineStatus {
    case sameToSingleLabel
    case halfWithSingleLabel
    case custom
}
// MARK: - 配置工具类
@objcMembers open class XMPageConfig:NSObject {
    /// 是否复用Cell，默认否。（复用cell的话需要频繁移除和添加childView）
    open var reuseCell = false
    /// icon显示的情况下，默认图的名称
    open var placeholderImageName = "zhuti"
    /// icon显示与隐藏
    open var iconHiden:Bool = true
    /// 加号的显示与隐藏
    open var addBitnHiden:Bool = false
    /// 加号的位置
    open var addBitnIsBottom:Bool = false
    /// 右侧按钮图片
    open var addBitnImg:UIImage? = nil
    /// 下划线显示与隐藏
    open var currentLineHiden:Bool = false
    /// 是否需要解决返回手势冲突（当使用者未设置导航控制的手势代理时使用）
    open var allowNavBackPanGestureRecognizer:Bool = false
//    /// 自动布局title的宽度
//    open var aotuTitleWidth:Bool = true
    /// 字体大小
    open var titleFont:CGFloat = 15
    /// 文字选中颜色
    open var titleSelectedColor:UIColor = .orange
    /// 单条分割线颜色
    open var singleLineColor:UIColor = .gray
    /// 文字未选中颜色
    open var titleNormalColor:UIColor = .lightGray
    /// titleView scroll背景颜色
    open var titleViewBackColor:UIColor = .white
    /// titleView 选中背景颜色
    open var titleViewBackSelectedColor:UIColor = .white
    /// 下划线颜色
    open var currentLineColor:UIColor = .orange
    /// 下划线自定义默认宽度
    open var currentLineWidth:CGFloat = 30
    /// 下划线自定义默认高的
    open var currentLineHeight:CGFloat = 5
    /// 图标大小
    open var iconWidth:CGFloat = 20
    /// 默认下划线模式
    var lineStatus:selectedLineStatus = .halfWithSingleLabel
    /// 单个label菜单宽度（-1为平分titleViewFrame宽度/0为自适应/其他正值为设置的固定值）
    open var singleTitleWidth:CGFloat = 0
    /// 设置titleview的frame
    open var titleViewFrame:CGRect = CGRect(x: 0, y: 0, width: kScreenWidth, height: 30)
    /// 整个pageview的frame
    open var pageViewFrame:CGRect = CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight - XMTool.navigationBarHeight() - XMTool.tabBarHeight())
    // selected-》normal变化色差
    open var chromatismSelect:(r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)!
    // normal-》selected变化色差
    open var chromatismNormal:(r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)!
}

// MARK: - 各种事件代理

@objc protocol XMPagesDelegate:NSObjectProtocol {
    
    //点击选择了哪一页
    @objc  func selectedPage(pageTag:Int)
    //滑动选择了哪一页
    @objc  func scrollToPage(pageTag:Int)
    //正在翻页
    @objc  func scrollDidScrolling(startPageTag:Int,endPageTag:Int,progress:CGFloat)
    //点击了加号
    @objc  func addBtnClicked()
}
extension XMPagesDelegate{
    //默认实现
    func selectedPage(pageTag:Int){print("extension selectedPage")}
    //默认实现
    func scrollToPage(pageTag:Int){print("extension scrollToPage")}
    //默认实现
    func scrollDidScrolling(startPageTag:Int,endPageTag:Int,progress:CGFloat){print("start page =\(startPageTag),end page = \(endPageTag),progress = \(progress)")}
}
// MARK: - 菜单实现

/// 自定义滚动菜单
@objcMembers class XMPages: NSObject {
    
    /// 配置实例化
    private var pageConfig:XMPageConfig = XMPageConfig()
    
    lazy private var titleView:UIScrollView = {
        let scrollV = UIScrollView.init()
        scrollV.bounces = false
        if #available(iOS 13.0, *) {
            scrollV.automaticallyAdjustsScrollIndicatorInsets = false
        } else {
            // Fallback on earlier versions
        }
        scrollV.showsHorizontalScrollIndicator = false
        scrollV.showsVerticalScrollIndicator = false
        scrollV.alwaysBounceHorizontal = false
        scrollV.isScrollEnabled = true
        return scrollV
    }()
    private var addBtn:UIButton = UIButton.init(type: .custom)
    private let addBtnSize = CGSize(width: 20, height: 20)
    private var titles:[String] = [String]()
    private var urls:[String] = [String]()
    private var singleLabelArray:[UILabel] = [UILabel]()
    private var singleTitleViewArray:[UIView] = [UIView]()
    private var viewControllers:[UIViewController] = [UIViewController]()
    private var currentLabel:UILabel!
    private var TapPaging:Bool = false
    private var currentLineLabel:UILabel = UILabel.init()
    private var lastOffset:CGFloat = 0.0
    lazy private var collectionView:UICollectionView = {
        let size = CGSize(width: self.pageConfig.pageViewFrame.size.width, height: self.pageConfig.pageViewFrame.size.height)
        let flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()
        flowLayout.itemSize = size
        flowLayout.minimumLineSpacing = 0
        flowLayout.minimumInteritemSpacing = 0
        flowLayout.scrollDirection = .horizontal
        let collectionView = UICollectionView.init(frame: CGRect(x: self.pageConfig.pageViewFrame.origin.x, y: self.pageConfig.pageViewFrame.origin.y, width: size.width, height: size.height), collectionViewLayout: flowLayout)
        collectionView.backgroundColor = .white
        
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.dataSource = self
        collectionView.delegate = self
        if pageConfig.reuseCell{
            collectionView.register(XMPageCell.self, forCellWithReuseIdentifier: "XMPageCell")
        }
        collectionView.isPagingEnabled = true
        collectionView.bounces = false
        return collectionView
    }()
    private weak var parentView:UIView!
    private weak var parentHeaderView:UIView!
    var lastView:UIView? = nil
    open weak var delegate:XMPagesDelegate?
    /// 构造函数
    /// - Parameters:
    ///   - titles: 标签数组
    ///   - viewControllers: 子控制器数组
    ///   - parentCtr: 添加到哪个控制器上
    ///   - pageConfig: 标签工具配置类
    public init(titles:[String],viewControllers:[UIViewController],parentHeaderView:UIView,parentView:UIView,pageConfig:XMPageConfig) {
        super.init()
        self.titles = titles;self.viewControllers = viewControllers;self.parentView = parentView;self.pageConfig = pageConfig;self.parentHeaderView = parentHeaderView;
        delegate = parentView as? XMPagesDelegate
        setUpUI()
    }
    /// 构造函数
    /// - Parameters:
    ///   - titles: 标签数组
    ///   - iconUrls: iconUrl数组
    ///   - viewControllers: 子控制器数组
    ///   - parentCtr: 添加到哪个控制器上
    ///   - pageConfig: 标签工具配置类
    public init(titles:[String],iconUrls:[String],viewControllers:[UIViewController],parentHeaderView:UIView,parentView:UIView,pageConfig:XMPageConfig) {
        super.init()
        self.titles = titles;self.urls = iconUrls;self.viewControllers = viewControllers;self.parentView = parentView;self.pageConfig = pageConfig;self.parentHeaderView = parentHeaderView;
        delegate = parentView as? XMPagesDelegate
        pageConfig.iconHiden = false
        setUpUI()
    }
    
    /// 构造函数
    /// - Parameters:
    ///   - titles: 标签数组
    ///   - viewControllers: 子控制器数组
    ///   - parentView: 添加到哪个view上
    ///   - parentHeaderView: 组头添加到哪个view上
    public init(titles:[String],viewControllers:[UIViewController],parentView:UIView,parentHeaderView:UIView) {
        super.init()
        self.titles = titles;self.viewControllers = viewControllers;self.parentView = parentView;self.parentHeaderView = parentHeaderView;
        delegate = parentView as? XMPagesDelegate
        setUpUI()
    }
    /// 构造函数
    /// - Parameters:
    ///   - titles: 标签数组
    ///   - iconUrls: icon数组
    ///   - viewControllers: 子控制器数组
    ///   - parentView: 添加到哪个view上
    ///   - parentHeaderView: 组头添加到哪个view上
    public init(titles:[String],iconUrls:[String],viewControllers:[UIViewController],parentView:UIView,parentHeaderView:UIView) {
        super.init()
        self.titles = titles;self.urls = iconUrls;self.viewControllers = viewControllers;self.parentView = parentView;self.parentHeaderView = parentHeaderView;
        delegate = parentView as? XMPagesDelegate
        pageConfig.iconHiden = false
        setUpUI()
    }
    
    //重载
    public func reSetChildControllers(titles:[String],iconUrls:[String],viewControllers:[UIViewController],parentHeaderView:UIView,parentView:UIView,pageConfig:XMPageConfig){
        lastView = nil
        //删除所有view
        for (_,ctr) in self.viewControllers.enumerated() {
            ctr.willMove(toParent: nil)
            ctr.view.removeFromSuperview()
            ctr.removeFromParent()
        }
        self.urls.removeAll()
        self.viewControllers.removeAll()
        self.singleLabelArray.removeAll()
        self.singleTitleViewArray.removeAll()
        for (_,titlelb) in self.titleView.subviews.enumerated() {
            titlelb.removeFromSuperview()
        }
        for (_,titlelb) in self.parentView.subviews.enumerated() {
            titlelb.removeFromSuperview()
        }
        self.titleView.removeFromSuperview()
        //重载
        collectionView = {
            let size = CGSize(width: self.pageConfig.pageViewFrame.size.width, height: self.pageConfig.pageViewFrame.size.height)
            let flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()
            flowLayout.itemSize = size
            flowLayout.minimumLineSpacing = 0
            flowLayout.minimumInteritemSpacing = 0
            flowLayout.scrollDirection = .horizontal
            let collectionView = UICollectionView.init(frame: CGRect(x: self.pageConfig.pageViewFrame.origin.x, y: self.pageConfig.pageViewFrame.origin.y, width: size.width, height: size.height), collectionViewLayout: flowLayout)
            //        collectionView.backgroundColor = .white
            collectionView.showsHorizontalScrollIndicator = false
            collectionView.dataSource = self
            collectionView.delegate = self
            if pageConfig.reuseCell{
                // 动态注册单元格
                collectionView.registerClassForCellReuseIdentifier(cellId)
            }
            collectionView.isPagingEnabled = true
            collectionView.bounces = false
            return collectionView
        }()
        //新建
        self.titles = titles;self.viewControllers = viewControllers;self.parentView = parentView;self.parentHeaderView = parentHeaderView;self.urls = iconUrls
        delegate = parentView as? XMPagesDelegate
        setUpUI()
        self.titleView.contentOffset.x = 0
        
    }
    //更新色差
    public func updateColor(){
        pageConfig.chromatismNormal = self.transColorBeginColorAndEndColor(beginColor: pageConfig.titleNormalColor, endColor: pageConfig.titleSelectedColor)
        pageConfig.chromatismSelect = self.transColorBeginColorAndEndColor(beginColor: pageConfig.titleSelectedColor, endColor: pageConfig.titleNormalColor)
    }
    //更新文字
    public func updateTitles(){
        for (index,title) in self.titles.enumerated() {
            if singleLabelArray.count > 0{
                let label:UILabel = singleLabelArray[index]
                label.text = title
            }
        }
    }
    deinit{
        //判断是否允许解决返回手势冲突，如允许，则在销毁的时候重置代理给原来的导航控制器
        if pageConfig.allowNavBackPanGestureRecognizer{
            if let current = UIViewController.current() as? UINavigationController{
                if let gesture = current.interactivePopGestureRecognizer {
                    gesture.delegate = current as? any UIGestureRecognizerDelegate
                }
            }else{
                if let gesture = UIViewController.current().navigationController?.interactivePopGestureRecognizer {
                    gesture.delegate = UIViewController.current().navigationController as? any UIGestureRecognizerDelegate
                }
            }
        }
    }
    public func canScrollEnabled(canPage:Bool){
        self.collectionView.isScrollEnabled = canPage
    }
    private func setUpUI(){
        if self.urls.count == 0 {
            pageConfig.iconHiden = true
        }
        if titles.count != viewControllers.count {
            XMLog("[XMPages]warning-->数组不匹配")
            return
        }
        if pageConfig.iconHiden == false && titles.count != urls.count{
            
            XMLog("[XMPages]warning-->数组信息不匹配")
            return
            
        }
        if parentView == nil {
            XMLog("[XMPages]warning-->父视图不存在")
            return
        }
        titleView.backgroundColor = pageConfig.titleViewBackColor
        updateColor()
        titleView.frame = pageConfig.titleViewFrame
        parentHeaderView.addSubview(titleView)
        parentView.addSubview(collectionView)
        addBtn.isHidden = pageConfig.addBitnHiden
        if self.addBtn.isHidden == false && pageConfig.addBitnIsBottom == true{
            titleView.frame = CGRect(x: pageConfig.titleViewFrame.origin.x, y: pageConfig.titleViewFrame.origin.y, width: pageConfig.titleViewFrame.size.width - self.addBtnSize.width - 5, height: pageConfig.titleViewFrame.height)
            addBtn.frame = CGRect(x: parentHeaderView.frame.size.width - addBtnSize.width - 5, y: pageConfig.titleViewFrame.origin.y + titleView.frame.size.height / 2 - addBtnSize.height / 2, width: addBtnSize.width, height: addBtnSize.height)
        }else {
            addBtn.frame = CGRect(x: parentHeaderView.frame.size.width - addBtnSize.width - 5, y: titleView.frame.size.height / 2 - addBtnSize.height / 2, width: addBtnSize.width, height: addBtnSize.height)
        }
        if let addimg = pageConfig.addBitnImg{
            addBtn.setImage(addimg, for: .normal)
        }
        for (index,title) in self.titles.enumerated() {
            let targetView = UIView.init()
//            targetView.layer.cornerRadius = 5
            targetView.layer.masksToBounds = true
//            targetView.layer.borderWidth = 0.5
//            targetView.layer.borderColor = UIColor.gray.cgColor
            targetView.backgroundColor = pageConfig.titleViewBackColor // 设置背景颜色
            let label:UILabel = UILabel.init()
            targetView.addSubview(label)
            titleView.addSubview(targetView)
//            label.translatesAutoresizingMaskIntoConstraints = false
            label.backgroundColor = pageConfig.titleViewBackColor
            label.tag = index
            label.text = title
//            label.layer.cornerRadius = 0
//            label.layer.masksToBounds = true
            label.layer.borderWidth = 0
            label.layer.borderColor = UIColor.clear.cgColor
            label.numberOfLines = 1
            label.lineBreakMode = .byTruncatingTail
            label.textColor = pageConfig.titleNormalColor
            label.textAlignment = .center
            label.font = UIFont.systemFont(ofSize: pageConfig.titleFont)
            let vwidth: CGFloat
            if pageConfig.singleTitleWidth == 0 {
                // Auto width adjustment
                vwidth = calculateLabelTextWidth(label: label) + 20
            } else if pageConfig.singleTitleWidth == -1 {
                pageConfig.singleTitleWidth = ceil(pageConfig.titleViewFrame.width / CGFloat(titles.count))
                vwidth = pageConfig.singleTitleWidth
            } else {
                vwidth = pageConfig.singleTitleWidth
            }
            
            targetView.frame = CGRect(
                x: (lastView?.frame.maxX ?? 0),
                y: 0,
                width: vwidth,
                height: pageConfig.titleViewFrame.height
            )
            label.isUserInteractionEnabled = true
            label.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action:#selector(self.labelClick(tap:)) ))
            singleLabelArray.append(label)
            singleTitleViewArray.append(targetView)
            
            if pageConfig.iconHiden == false
            {
                let url = self.urls[index]
                
                let icon = UIImageView.init()
                icon.backgroundColor = .clear
                targetView.addSubview(icon)
                if url.count > 0 {
//                    icon.sd_setImage(with: URL(string: url), placeholderImage: UIImage(named: pageConfig.placeholderImageName), context: nil)
                    // 图片 URL
                    if let url = URL(string: url) {
                        // 异步下载图片
                        URLSession.shared.dataTask(with: url) { (data, response, error) in
                            if let data = data, let image = UIImage(data: data) {
                                // 更新 UI 必须在主线程
                                DispatchQueue.main.async {
                                    icon.image = image
                                }
                            } else if let error = error {
                                print("图片加载失败: \(error.localizedDescription)")
                            }
                        }.resume()
                    }
                }else {
                    icon.image = UIImage(named: pageConfig.placeholderImageName)
                }
                
                icon.frame = CGRect(x: 0, y: pageConfig.titleViewFrame.height/2 - pageConfig.iconWidth/2, width: pageConfig.iconWidth, height: pageConfig.iconWidth)
                if pageConfig.singleTitleWidth == 0 {
                    label.frame = CGRect(x: icon.frame.size.width, y: 0, width: calculateLabelTextWidth(label: label), height: pageConfig.titleViewFrame.height)
                }else {
                    label.frame = CGRect(x: icon.frame.size.width, y: 0, width: pageConfig.singleTitleWidth - icon.frame.size.width, height: pageConfig.titleViewFrame.height)

                }
                
            }else{
                label.frame = CGRect(x: 0, y: 0, width: vwidth, height: pageConfig.titleViewFrame.height)
            }
            parentView.findViewController()?.addChild(self.viewControllers[index])
            lastView = targetView
        }
        addBtn.addTarget(self, action: #selector(self.addBtnClick), for: .touchUpInside)
        parentHeaderView.addSubview(addBtn)
        currentLabel = singleLabelArray.first
        currentLabel.textColor = pageConfig.titleSelectedColor
        currentLineLabel.backgroundColor = pageConfig.currentLineColor
        currentLineLabel.frame.size = CGSize(width: (pageConfig.lineStatus == .halfWithSingleLabel ? pageConfig.lineStatus == .custom ? pageConfig.currentLineWidth : currentLabel.superview!.frame.size.width/2 : currentLabel.superview!.frame.size.width ), height: pageConfig.currentLineHeight)
  
        currentLineLabel.center.x = currentLabel.superview!.center.x
        currentLineLabel.xmbottom = pageConfig.titleViewFrame.height
        currentLineLabel.isHidden = pageConfig.currentLineHiden
//        pageConfig.currentLineWidth = currentLineLabel.frame.width
        titleView.addSubview(currentLineLabel)
        titleView.contentSize = CGSize(width: lastView?.frame.maxX ?? 0, height: 0)
        let grayline:UILabel = UILabel.init(frame: CGRect(x: 0, y: 0, width: titleView.contentSize.width, height: 0.5))
        grayline.backgroundColor = pageConfig.singleLineColor
        grayline.frame = CGRect(x: 0, y: currentLineLabel.xmbottom - 0.5, width: titleView.contentSize.width + kScreenWidth, height: 0.5)
        titleView.addSubview(grayline)
        collectionView.reloadData()
        
        if pageConfig.allowNavBackPanGestureRecognizer {
            // 重置导航控制器返回手势的代理，需要在销毁的时候重置回去
            if let gesture = parentView.findViewController()?.navigationController?.interactivePopGestureRecognizer {
                gesture.delegate = self
            }
        }
    }
    func calculateLabelTextWidth(label: UILabel) -> CGFloat {
        guard let text = label.text else { return 0 }
        let size = (text as NSString).size(withAttributes: [NSAttributedString.Key.font: label.font ?? UIFont.systemFont(ofSize: 14)])
        //使用循环计算label尺寸, 循环创建label时有可能出现右边缘黑线的问题,  这是因为计算出得size可能的值会是30.31123323…… 这样的数,   猜想: 而像素值显示的时候不可能出现显示半个像素的情况, 那么不足一个像素的值就会被忽略掉, 在分辨率较低的机型上不会出现, 而分辨率较高的则不会忽略, 就出现了黑线。
        //<p>计算出来的UILabel尺寸，向上取整</p>
        return ceil(size.width)
    }
    @objc func addBtnClick(){
        self.delegate?.addBtnClicked()
    }
}
extension UIView {
    func findViewController() -> UIViewController? {
        if let nextResponder = self.next as? UIViewController {
            return nextResponder
        } else if let nextResponder = self.next as? UIView {
            return nextResponder.findViewController()
        } else {
            return nil
        }
    }
    func parentViewController() -> UIViewController? {
        var parentResponder: UIResponder? = self
        while parentResponder != nil {
            parentResponder = parentResponder!.next
            if let viewController = parentResponder as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}
class XMPageCell: UICollectionViewCell {
    
    var viewController: UIViewController?
    
    override func prepareForReuse() {
        super.prepareForReuse()
        // 从内容视图中移除视图控制器的视图
//        if let view = viewController?.view {
//            view.removeFromSuperview()
//        }
    }
    
    func configure(with viewController: UIViewController,reuseCell:Bool = false) {
        // 从内容视图中移除视图控制器的视图
        if reuseCell {
            if let view = viewController.view{
                view.removeFromSuperview()
                self.viewController = nil
            }
        }
        // 将视图控制器的视图添加到内容视图中
        if self.viewController == nil {
            if let view = viewController.view {
                view.frame = contentView.bounds
                contentView.addSubview(view)
            }
        }
        self.viewController = viewController
    }
}


extension UICollectionView {
    func registerClassForCellReuseIdentifier(_ identifier: String) {
        if self.registeredIdentifiers.contains(identifier) {
            return
        }
        self.register(XMPageCell.self, forCellWithReuseIdentifier: identifier)
        self.registeredIdentifiers.insert(identifier)
    }
    
    private struct AssociatedKeys {
        static var registeredIdentifiers:UInt8 = 0
    }
   
    private var registeredIdentifiers: Set<String> {
        get {
            if let identifiers = objc_getAssociatedObject(self, &AssociatedKeys.registeredIdentifiers) as? Set<String> {
                return identifiers
            }
            let identifiers = Set<String>()
            self.registeredIdentifiers = identifiers
            return identifiers
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.registeredIdentifiers, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}

// MARK: - 代理方法们

extension XMPages:UICollectionViewDataSource,UICollectionViewDelegate,UIGestureRecognizerDelegate{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        titles.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        var cellIdentifier = "XMPageCell\(indexPath.item)"
        if pageConfig.reuseCell{
            cellIdentifier = cellId
        }else{
            // 动态注册单元格（如果注册过了就在方法内return）
            collectionView.registerClassForCellReuseIdentifier(cellIdentifier)
        }
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! XMPageCell
        
        // 实例化或获取你想展示的视图控制器
        let viewController = getViewController(for: indexPath)
        
        // 使用视图控制器配置单元格
        cell.configure(with: viewController,reuseCell: pageConfig.reuseCell)
        
        return cell
    }
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if TapPaging {
            //点击触发到滚动时不响应下面的方法
            return
        }
        //手动滚动时才触发
        let scrollX = scrollView.contentOffset.x
        let proportionUpInt = (ceil(scrollX / pageConfig.pageViewFrame.width))
        let proportionDownInt = (floor(scrollX / pageConfig.pageViewFrame.width))
        let proportion = ( scrollX - proportionDownInt * pageConfig.pageViewFrame.width ) / (pageConfig.pageViewFrame.width / 2)
        var colorProportion = ( scrollX - proportionDownInt * pageConfig.pageViewFrame.width) / (pageConfig.pageViewFrame.width)
        var proportionAll:CGFloat = 0.0
        //这里还需要修改。找到下一个和上一个的位置
        if proportion > 1{
            proportionAll = 2 - proportion
            let currentLineWidth = (pageConfig.lineStatus == .halfWithSingleLabel ? pageConfig.lineStatus == .custom ? pageConfig.currentLineWidth : singleTitleViewArray[Int(proportionUpInt)].frame.size.width/2 : singleTitleViewArray[Int(proportionUpInt)].frame.size.width )
            let currentLabelW = singleTitleViewArray[Int(proportionUpInt)].frame.width
            let nextLabelW = singleTitleViewArray[Int(proportionDownInt)].frame.width
            currentLineLabel.xmwidth = currentLineWidth + nextLabelW * (proportionAll)
            currentLineLabel.xmright =  singleTitleViewArray[Int(proportionUpInt)].frame.maxX - (currentLabelW - currentLineWidth)/2
        }else {
            proportionAll = proportion
            let currentLineWidth = (pageConfig.lineStatus == .halfWithSingleLabel ? pageConfig.lineStatus == .custom ? pageConfig.currentLineWidth : singleTitleViewArray[Int(proportionDownInt)].frame.size.width/2 : singleTitleViewArray[Int(proportionDownInt)].frame.size.width )
            let currentLabelW = singleTitleViewArray[Int(proportionDownInt)].frame.width
            let nextLabelW = singleTitleViewArray[Int(proportionUpInt)].frame.width
            currentLineLabel.xmwidth = currentLineWidth + nextLabelW * (proportionAll)
            currentLineLabel.xmleft = singleTitleViewArray[Int(proportionDownInt)].frame.minX  + (currentLabelW - currentLineWidth)/2
        }
        //由于 colorProportion 在正好滚动到正页面后又会初始化为0（因为要作为过渡系数，范围是0.0001-0.99999），所以当其为0时就转成1
        // TODO: - 可以继续优化一下（尤其是page-的时候颜色的变化）
        if scrollX - lastOffset > 0 {
            if colorProportion == 0 {
                colorProportion = 1
            }
            //page+
            if Int(proportionUpInt) < self.singleLabelArray.count {
                let rightLabel = self.singleLabelArray[Int(proportionUpInt)]
                if scrollX > CGFloat(Float(currentLabel.tag)) * pageConfig.pageViewFrame.width {
                    rightLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: colorProportion,marginArray: pageConfig.chromatismNormal)
                    currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleSelectedColor, coe: ( colorProportion),marginArray: pageConfig.chromatismSelect)
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionDownInt), endPageTag: Int(proportionUpInt), progress: proportionAll)
                }else{
//                    print("page-中途返回")
                    if proportionDownInt >= 0{
                        let leftLabel = self.singleLabelArray[Int(proportionDownInt)]
                        leftLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleSelectedColor, coe: colorProportion,marginArray: pageConfig.chromatismSelect)
                        currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: ( colorProportion),marginArray: pageConfig.chromatismNormal)
                    }
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionUpInt), endPageTag: Int(proportionDownInt), progress: proportionAll)
                }
                
            }
            
        }else{
            //page-
            if proportionDownInt >= 0 {
                
                let leftLabel = self.singleLabelArray[Int(proportionDownInt)]
                if scrollX >= CGFloat(Float(currentLabel.tag)) * pageConfig.pageViewFrame.width {
                    //中途返回
//                    print("page+中途返回")
                    if Int(proportionUpInt) < self.singleLabelArray.count {
                        
                        let rightLabel = self.singleLabelArray[Int(proportionUpInt)]
                        rightLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: colorProportion,marginArray: pageConfig.chromatismNormal)
                        currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleSelectedColor, coe: ( colorProportion),marginArray: pageConfig.chromatismSelect)
                    }
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionDownInt), endPageTag: Int(proportionUpInt), progress: proportionAll)
                    
                }else{
                    //正常滑动
//                    print(colorProportion)
                    leftLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe:1 - colorProportion,marginArray: pageConfig.chromatismNormal)
                    currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: (colorProportion),marginArray: pageConfig.chromatismNormal)
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionUpInt), endPageTag: Int(proportionDownInt), progress: proportionAll)
                }
                
            }
        }
        lastOffset = scrollX
    }
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
       //点击titlelabel自动滚动结束后调用
        TapPaging = false
    }
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        currentLabel.backgroundColor = pageConfig.titleViewBackColor
        currentLabel.superview!.backgroundColor = pageConfig.titleViewBackColor
        //自动滑动停止
        let scrollX = scrollView.contentOffset.x
        let proportionInt:Int = Int(scrollX / pageConfig.pageViewFrame.width)
        currentLabel = singleLabelArray[proportionInt]
        currentLabel.textColor = pageConfig.titleSelectedColor//防止因为中途返回而导致bug
        currentLabel.superview!.backgroundColor = pageConfig.titleViewBackSelectedColor
        currentLabel.backgroundColor = pageConfig.titleViewBackSelectedColor
        if ((delegate?.responds(to: #selector(delegate?.scrollToPage(pageTag:)))) != nil) {
            delegate!.scrollToPage(pageTag: proportionInt)
        }
        //让组头跟着滚动
        //自动
        let add = pageConfig.addBitnHiden ? 0 : (addBtn.frame
            .width + 5)
        let off:CGFloat = (self.titleView.contentSize.width - self.titleView.frame.width +   lastView!.frame.width + add) * CGFloat(CGFloat(proportionInt) / CGFloat(self.titles.count))
        UIView.animate(withDuration: 0.3) {
            self.titleView.contentOffset = CGPoint(x: off, y: 0)
        }
        self.viewControllers[proportionInt].didMove(toParent: parentView.findViewController())
        //防止滑动过快，导致中间的label文字没有变色的问题
        for tempLabel in singleLabelArray {
            if tempLabel != currentLabel{
                tempLabel.textColor = pageConfig.titleNormalColor
            }
        }
    }
    func getViewController(for indexPath: IndexPath) -> UIViewController {
        // 返回给定 indexPath 对应的视图控制器
        // 这可能涉及实例化一个新的视图控制器或重用现有的视图控制器
        return self.viewControllers[indexPath.item]
    }
    // UIGestureRecognizerDelegate 方法，处理手势冲突
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        // 如果是返回手势，则允许同时识别
        if gestureRecognizer == parentView.findViewController()?.navigationController?.interactivePopGestureRecognizer {
            
            return parentView.findViewController()?.navigationController?.viewControllers.count ?? 0 > 1
        }
        return false
    }
}
// MARK: - 颜色相关

extension XMPages{
    //根据颜色来返回rgb
    private func getRGBDictionaryByColor(originColor:UIColor) -> ((r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)){
        var r:CGFloat = 0;var g:CGFloat = 0;var b:CGFloat = 0;var a:CGFloat = 0
        
        r = originColor.r()
        g = originColor.g()
        b = originColor.b()
        a = originColor.a()
        return (r,g,b,a)
    }
    //获取色差
    public func transColorBeginColorAndEndColor(beginColor:UIColor,endColor:UIColor) -> ((r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)){
        let beginColorArr = getRGBDictionaryByColor(originColor: beginColor)
        let endColorArr = getRGBDictionaryByColor(originColor: endColor)
       
        return(endColorArr.r - beginColorArr.r,endColorArr.g - beginColorArr.g , endColorArr.b - beginColorArr.b,endColorArr.a - beginColorArr.a)
    }
    //根据色差和过度系数来确定当前颜色
    private func getCurrentColorWithColor(beginColor:UIColor,coe:CGFloat,marginArray:(r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat))
    -> UIColor
    {
        let beginColorArr = getRGBDictionaryByColor(originColor: beginColor)
        
        let r = beginColorArr.r + coe * marginArray.r
        let g = beginColorArr.g + coe * marginArray.g
        let b = beginColorArr.b + coe * marginArray.b
        let a = beginColorArr.a + coe * marginArray.a
        return UIColor.init(red: r, green: g, blue: b, alpha: a)
    }
}
// MARK: - 点击事件

extension XMPages{
    @objc private func labelClick(tap:UITapGestureRecognizer){
        guard let label = tap.view as? UILabel else { return }
               
        if label == currentLabel { return }
        TapPaging = true
        label.textColor = pageConfig.titleSelectedColor
        currentLabel.textColor = pageConfig.titleNormalColor
        currentLabel.backgroundColor = pageConfig.titleViewBackColor
        currentLabel.superview!.backgroundColor = pageConfig.titleViewBackColor
        currentLabel = label
        currentLabel.superview!.backgroundColor = pageConfig.titleViewBackSelectedColor
        currentLabel.backgroundColor = pageConfig.titleViewBackSelectedColor
        let currentlinew = (self.pageConfig.lineStatus == .halfWithSingleLabel ? self.pageConfig.lineStatus == .custom ? self.pageConfig.currentLineWidth : self.currentLabel.superview!.frame.size.width/2 : self.currentLabel.superview!.frame.size.width )
        UIView.animate(withDuration: 0.3) {
//            self.currentLineLabel.center.x = self.currentLabel.superview!.center.x
            self.currentLineLabel.frame = CGRect(x: self.currentLabel.superview!.frame.origin.x + currentlinew / 2, y: self.currentLineLabel.frame.origin.y, width: currentlinew, height: self.pageConfig.currentLineHeight)
        }
        collectionView.scrollToItem(at: IndexPath(item: label.tag, section: 0), at: .centeredHorizontally, animated: true)
        let add = pageConfig.addBitnHiden ? 0 : (addBtn.frame
            .width + 5)
        let off:CGFloat = (self.titleView.contentSize.width - self.titleView.frame.width +   lastView!.frame.width + add) * CGFloat(CGFloat(label.tag) / CGFloat(self.titles.count))
        UIView.animate(withDuration: 0.3) {
            self.titleView.contentOffset = CGPoint(x: off, y: 0)
//            self.currentLineLabel.frame = CGRect(x: self.currentLabel.superview!.frame.origin.x + currentlinew / 2, y: self.currentLineLabel.frame.origin.y, width: currentlinew, height: self.pageConfig.currentLineHeight)
        }
        if ((delegate?.responds(to: #selector(delegate?.selectedPage(pageTag:)))) != nil) {
            delegate!.selectedPage(pageTag: label.tag)
        }
        
    }
}

//UIColor的延展
//将color转换成RGB
extension UIColor {
    func r() -> CGFloat {
        return self.cgColor.components?[0] ?? 0
    }
    
    func g() -> CGFloat {
        let count = self.cgColor.numberOfComponents
        if (count == 2) {
            return self.cgColor.components?[0] ?? 0
        } else {
            return self.cgColor.components?[1] ?? 0
        }
    }
    
    func b() -> CGFloat {
        let count = self.cgColor.numberOfComponents;
        if (count == 2) {
            return self.cgColor.components?[0] ?? 0
        } else {
            return self.cgColor.components?[2] ?? 0
        }
    }
    
    func a() -> CGFloat {
        let count = self.cgColor.numberOfComponents;
        return self.cgColor.components?[count - 1] ?? 0
    }
}
